In [ ]:
%matplotlib inline
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
import uqer
from uqer import DataAPI as api
from QuantLib import *
plt.style.use('fivethirtyeight')
uqer.Client(token='f1b9bea1d0b4e489c5ab9b69c3e2326a1bee6057af858067dbd1546453f428b2')
In [ ]:
ru1801 = api.MktFutdGet(ticker='RU1801', beginDate='20170825', endDate='20171130', field='tradeDate,closePrice').set_index('tradeDate')
ru1801['closePrice'] = ru1801['closePrice'].astype(float)
ru1801.plot(figsize=(14, 7))
In [ ]:
start_date = Date(31, 8, 2017)
maturity_date = Date(30, 11, 2017)
freq = Period(1, Days)
volatility = 0.27
option_type = Option.Put
spot_price = ru1801.loc['2017-08-31', 'closePrice']
strike_price = np.mean(ru1801.loc['2017-08-25': '2017-08-31', 'closePrice'])
risk_free_rate = 0.
dividend_rate = 0.
day_count = Actual365Fixed()
calendar = China(China.SSE)
payoff = PlainVanillaPayoff(option_type, strike_price)
exercise = EuropeanExercise(maturity_date)
fixing_scheduler = Schedule(start_date, maturity_date, freq, calendar, Following, Following, DateGeneration.Backward, False)
fixing_dates = [d for d in fixing_scheduler][1:]
In [ ]:
calculation_date = start_date
Settings.instance().evaluationDate = calculation_date
spot_handle = RelinkableQuoteHandle(SimpleQuote(spot_price))
flat_ts = YieldTermStructureHandle(FlatForward(calculation_date, risk_free_rate, day_count))
dividend_yield = YieldTermStructureHandle(FlatForward(calculation_date, dividend_rate, day_count))
flat_vol_ts = BlackVolTermStructureHandle(BlackConstantVol(calculation_date, calendar, volatility, day_count))
bsm_process = BlackScholesMertonProcess(spot_handle, dividend_yield, flat_ts, flat_vol_ts)
option = DiscreteAveragingAsianOption(Average.Arithmetic, 0., 0, fixing_dates, payoff, exercise)
In [ ]:
engine = FdBlackScholesAsianEngine(bsm_process, 200, 100, 100)
In [ ]:
option.setPricingEngine(engine)
fdm_price = option.NPV()
fdm_delta = option.delta()
print("BSM ASIAN FDM price is {0:.4f}".format(fdm_price))
print("BSM ASIAN FDM delta is {0:.4f}".format(fdm_delta))
In [ ]:
engine = MCDiscreteArithmeticAPEngine(bsm_process, 'ld', controlVariate=True, requiredSamples=50000)
In [ ]:
%%time
option.setPricingEngine(engine)
mc_price = option.NPV()
price_delta = 0.001 * spot_price
new_quote1 = SimpleQuote(spot_price + price_delta)
new_quote2 = SimpleQuote(spot_price - price_delta)
spot_handle.linkTo(new_quote1)
price_bump_plus = option.NPV()
spot_handle.linkTo(new_quote2)
price_bump_minus = option.NPV()
mc_delta = (price_bump_plus - price_bump_minus) / 2. / price_delta
In [ ]:
print("BSM ASIAN MC price is {0:.4f}".format(mc_price))
print("BSM ASIAN MC delta is {0:.4f}".format(mc_delta))
In [ ]:
%%time
monitor_dates = [start_date]
fdm_npvs = [fdm_price]
fdm_deltas = [fdm_delta]
for i, date in enumerate(fixing_dates[:-1]):
past_fixings = i + 1
running_accumulator = np.sum(ru1801.loc[fixing_dates[0].ISO():date.ISO(), 'closePrice'])
# Model settings
calculation_date = date
Settings.instance().evaluationDate = calculation_date
spot_handle = RelinkableQuoteHandle(SimpleQuote(ru1801.loc[date.ISO(), 'closePrice']))
flat_ts = YieldTermStructureHandle(FlatForward(calculation_date, risk_free_rate, day_count))
dividend_yield = YieldTermStructureHandle(FlatForward(calculation_date, dividend_rate, day_count))
flat_vol_ts = BlackVolTermStructureHandle(BlackConstantVol(calculation_date, calendar, volatility, day_count))
bsm_process = BlackScholesMertonProcess(spot_handle, dividend_yield, flat_ts, flat_vol_ts)
option = DiscreteAveragingAsianOption(Average.Arithmetic, running_accumulator, past_fixings, fixing_dates[i+1:], payoff, exercise)
engine = FdBlackScholesAsianEngine(bsm_process, 200, 100, 100)
option.setPricingEngine(engine)
monitor_dates.append(date)
fdm_npvs.append(option.NPV())
fdm_deltas.append(option.delta())
In [ ]:
%%time
mc_npvs = [mc_price]
mc_deltas = [mc_delta]
for i, date in enumerate(fixing_dates[:-1]):
past_fixings = i + 1
running_accumulator = np.sum(ru1801.loc[fixing_dates[0].ISO():date.ISO(), 'closePrice'])
# Model settings
calculation_date = date
Settings.instance().evaluationDate = calculation_date
spot_handle = RelinkableQuoteHandle(SimpleQuote(ru1801.loc[date.ISO(), 'closePrice']))
flat_ts = YieldTermStructureHandle(FlatForward(calculation_date, risk_free_rate, day_count))
dividend_yield = YieldTermStructureHandle(FlatForward(calculation_date, dividend_rate, day_count))
flat_vol_ts = BlackVolTermStructureHandle(BlackConstantVol(calculation_date, calendar, volatility, day_count))
bsm_process = BlackScholesMertonProcess(spot_handle, dividend_yield, flat_ts, flat_vol_ts)
option = DiscreteAveragingAsianOption(Average.Arithmetic, running_accumulator, past_fixings, fixing_dates[i+1:], payoff, exercise)
engine = MCDiscreteArithmeticAPEngine(bsm_process, 'ld', controlVariate=True, requiredSamples=50000)
option.setPricingEngine(engine)
option.setPricingEngine(engine)
mc_npvs.append(option.NPV())
price_delta = 0.001 * spot_handle.value()
new_quote1 = SimpleQuote(spot_handle.value() + price_delta)
new_quote2 = SimpleQuote(spot_handle.value() - price_delta)
spot_handle.linkTo(new_quote1)
price_bump_plus = option.NPV()
spot_handle.linkTo(new_quote2)
price_bump_minus = option.NPV()
mc_delta = (price_bump_plus - price_bump_minus) / 2. / price_delta
mc_deltas.append(mc_delta)
In [ ]:
dates_series = [d.to_date() for d in monitor_dates]
delta_diff = np.array(fdm_deltas) - np.array(mc_deltas)
df = pd.DataFrame({'FDM NPV': np.array(fdm_npvs),
'MC NPV': np.array(mc_npvs),
'FDM $\Delta$': fdm_deltas,
'MC $\Delta$': mc_deltas},
index=dates_series)
In [ ]:
df.plot(figsize=(14, 7), secondary_y=['FDM NPV','MC NPV'], title='RU1801 Asian Option NPV & $\Delta$: 2017-09-01 ~ 2017-11-30')
In [ ]: